package com.example.qt.ptplatform.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.qt.ptplatform.dto.TrackerProtocol;
import com.example.qt.ptplatform.entity.Torrent;
import com.example.qt.ptplatform.entity.TorrentReport;
import com.example.qt.ptplatform.entity.User;
import com.example.qt.ptplatform.mapper.TorrentReportMapper;
import com.example.qt.ptplatform.service.UserService;
import com.example.qt.ptplatform.service.impl.TorrentServiceImpl;
import com.example.qt.ptplatform.utils.JsonResult;
import com.sun.org.apache.bcel.internal.generic.IFNONNULL;
import com.turn.ttorrent.bcodec.BEValue;
import com.turn.ttorrent.bcodec.BEncoder;
import com.turn.ttorrent.common.*;
import com.turn.ttorrent.common.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLDecoder;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RequestMapping(value = "torrent")
@RestController
@RequiredArgsConstructor
@Slf4j
public class TorrentController {

    private final TorrentServiceImpl torrentService;
    private final UserService userService;
    private final TorrentReportMapper torrentReportMapper;


    /**
     * 查询所有种子
     * @return
     */
    @RequestMapping(value = "findAllTorrentList", method = RequestMethod.GET)
    public List<Torrent> findTorrentList() {
        return torrentService.findAllTorrentList();
    }

    //根据tag查询种子
    @RequestMapping(value = "findTorrentList", method = RequestMethod.GET)
    public List<Torrent> findTorrentList(@RequestParam("q")  String tags) {
        return torrentService.findTorrentList(tags);
    }

    @GetMapping("/getTorrentDetails/{torrentId}")
    public JsonResult getTorrentDetails(@PathVariable("torrentId") int torrentId) {
        try {
            Torrent torrent = torrentService.getTorrentDetailsById(torrentId);
            if (torrent != null) {
                return JsonResult.success("获取种子详情成功", torrent);
            } else {
                return JsonResult.error("种子未找到");
            }
        } catch (Exception e) {
            return JsonResult.error("获取种子详情失败", e.getMessage());
        }
    }

    // 删除种子接口
    @DeleteMapping("/deleteTorrent")
    public JsonResult deleteTorrent(@RequestParam("user_id") int userId, @RequestParam("torrent_id") int torrentId) {
        try {
            // 调用 Service 层删除种子，返回不同的状态
            String result = torrentService.deleteTorrent(userId, torrentId);

            // 判断删除操作结果
            if ("SUCCESS".equals(result)) {
                return JsonResult.success("删除种子成功");
            } else if ("TRORENT_NOT_FOUND".equals(result)) {
                return JsonResult.error("种子不存在");
            } else if ("NO_PERMISSION".equals(result)) {
                return JsonResult.error("无权限删除该种子");
            } else {
                return JsonResult.error("删除种子失败");
            }
        } catch (Exception e) {
            // 处理异常，返回失败信息
            return JsonResult.error("删除种子失败", e.getMessage());
        }
    }

    // 获取用户上传的种子列表
    @GetMapping("/getUserTorrents")
    public JsonResult getUserTorrents(@RequestParam("user_id") int userId) {
        try {
            // 调用 Service 层获取用户上传的种子列表
            List<Torrent> userTorrents = torrentService.getUserTorrents(userId);

            // 判断是否找到了种子记录
            if (userTorrents != null && !userTorrents.isEmpty()) {
                return JsonResult.success("获取用户上传的种子列表成功", userTorrents);
            } else {
                return JsonResult.error("没有找到用户上传的种子");
            }
        } catch (Exception e) {
            // 处理异常，返回失败信息
            return JsonResult.error("获取种子列表失败", e.getMessage());
        }
    }

    @PostMapping("/uploadCoverImage")
    public JsonResult uploadCoverImage(@RequestParam("torrentId") Integer torrentId,
                                       @RequestParam("file") MultipartFile coverImageFile) {
        boolean success = torrentService.uploadCoverImage(torrentId, coverImageFile);
        if (success) {
            return JsonResult.success("封面图片上传成功！");
        } else {
            return JsonResult.error("上传失败，资源未找到！");
        }
    }

    @GetMapping("/getCoverImage")
    public ResponseEntity<byte[]> getCoverImage(@RequestParam("torrentId") Integer torrentId) {
        Torrent torrent = torrentService.getById(torrentId);
        if (torrent != null && torrent.getCoverImage() != null) {
            // 将二进制图片数据转换为 Base64 编码的字符串
            String base64Image = Base64.getEncoder().encodeToString(torrent.getCoverImage());

            // 返回 Base64 编码的图片字符串
//            20250529xxx
            ResponseEntity<byte[]> body = ResponseEntity.ok()
                    .contentType(MediaType.IMAGE_JPEG)
                    .body(torrent.getCoverImage());
            return body;
        }
        return ResponseEntity.status(HttpStatus.NOT_FOUND).build();  // 图片未找到
    }

    // 推荐系统接口
    @GetMapping("/recommend")
    public JsonResult recommendVideos(@RequestParam("torrentId") Integer torrentId) {
        try {
            // 调用 Service 层的推荐逻辑
            List<Torrent> recommendedTorrents = torrentService.recommendVideos(torrentId);
            return JsonResult.success("推荐视频获取成功", recommendedTorrents);
        } catch (RuntimeException e) {
            return JsonResult.error(e.getMessage());
        }
    }

    @PostMapping("/upload")
    public JsonResult uploadTorrent(@RequestParam("file") MultipartFile file, @RequestParam Integer userId){
        try(InputStream is = file.getInputStream()) {
            TorrentMetadata metadata = new TorrentParser().parse(file.getBytes());
            LambdaQueryWrapper<Torrent> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(Torrent::getInfoHash, metadata.getHexInfoHash());
            if(torrentService.count(wrapper) > 0){
                return JsonResult.error("种子已存在");
            }
            Torrent torrent = new Torrent();
            String paths = metadata.getFiles().stream().map(TorrentFile::getRelativePathAsString).collect(Collectors.joining(","));
            Long size = metadata.getFiles().stream().map(f -> f.size).reduce(0L, Long::sum);
            torrent.setTitle(file.getOriginalFilename());
            torrent.setUserId(userId);
            torrent.setSizeGB(size / 1024.0 / 1024.0 / 1024.0);
            torrent.setRealFilename(paths);
            torrent.setInfoHash(metadata.getHexInfoHash());
            torrent.setUploadTime(LocalDateTime.now());
            torrent.setDescription(metadata.getComment().orElse(""));
            torrentService.save(torrent);

        }catch (IOException e){
            return JsonResult.error("上传失败");
        }
        return JsonResult.success();
    }

    @PostMapping("/setPeer")
    public JsonResult setPeer(@RequestParam("peerId") String peerID, @RequestParam("userId") Integer userID){
        if(peerID == null || peerID.length() != 20){
            return JsonResult.error("peerId格式错误");
        }
        Optional<User> userOpt = userService.findByPeerID(peerID);
        if(userOpt.isPresent()){
            User user = userOpt.get();
            return JsonResult.error("peerId 已经跟用户: " + user.getUsername() + " 绑定");
        }
        User user = userService.getById(userID);
        if(user == null){
            return JsonResult.error("用户不存在");
        }
        user.setPeerId(peerID);
        userService.updateById(user);
        return JsonResult.success("设置成功");
    }


    @GetMapping("/announce")
    public ResponseEntity<byte[]> announce(TrackerProtocol trackerProtocol, HttpServletRequest request,    @RequestParam(value = "info_hash") String encodedInfoHash){
        log.info("client report: {}", trackerProtocol);
        HashMap<String, BEValue> map = new HashMap<>();
        try {
            byte[] bytes = URLDecoder.decode(request.getQueryString().split("info_hash=")[1].split("&")[0], StandardCharsets.ISO_8859_1.name()).getBytes(StandardCharsets.ISO_8859_1);
            String infoHash = TorrentUtils.byteArrayToHexString(bytes);
            Torrent torrent = torrentService.getOne(Wrappers.<Torrent>lambdaQuery().eq(Torrent::getInfoHash, infoHash));
            trackerProtocol.setInfo_hash(infoHash);
            if (torrent == null) {
                throw new RuntimeException("种子不存在");
            }
            Integer userId = trackerProtocol.getUser_id();
            if(userId == null){
                Optional<User> userOpt = userService.findByPeerID(trackerProtocol.getPeer_id());
                if (!userOpt.isPresent()) {
                    throw new RuntimeException("用户不存在");
                }
                User user = userOpt.get();
                userId = user.getUserId();
            }else{
                User user = userService.getById(userId);
                if(user == null) {
                    throw new RuntimeException("用户不存在");
                }
            }
            TorrentReport report = TorrentReport.builder()
                    .userId(userId )
                    .torrentId(torrent.getTorrentId())
                    .infoHash(infoHash)
                    .build();
            BeanUtils.copyProperties(trackerProtocol, report);

            torrentReportMapper.insert(report);
            map.put("interval", new BEValue(30));
            map.put("peers", new BEValue(Collections.emptyList()));
            ByteBuffer bencode = BEncoder.bencode(map);
            //调用增量卡逻辑！！！！
            //userService.updateUserUploadCountByDouble(userId, torrent.getTorrentId());

            return ResponseEntity.ok(bencode.array());

        }catch (Exception e){
            try{
                String message = e.getMessage();
                message = message == null ? "" : message;
                log.error("announce error", e);
                map.put("failure reason", new BEValue(message    , "UTF-8"));
                return ResponseEntity.ok(BEncoder.bencode(map).array());
            }catch (Exception ex){
                log.error("announce error ", ex);
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error".getBytes());
            }
        }
    }

    // 搜索接口，接受前端传来的关键词
    @GetMapping("/search")
    public List<Torrent> searchTorrents(@RequestParam String keyword) {
        // 调用服务层的方法，获取搜索结果
        return torrentService.searchTorrents(keyword);
    }

    // 根据 tag 关键字筛选记录
    @GetMapping("/searchByTag")
    public List<Torrent> searchTorrentsByTag(@RequestParam String tag) {
        return torrentService.searchTorrentsByTag(tag);
    }

    @GetMapping("/getInfoHash")
    public JsonResult getInfoHash(@RequestParam("torrentId") Integer torrentId) {
        try {
            Torrent torrent = torrentService.getById(torrentId);
            if (torrent != null && torrent.getInfoHash() != null) {
                return JsonResult.success(torrent.getInfoHash());
            } else {
                return JsonResult.error("种子不存在或未包含 info_hash");
            }
        } catch (Exception e) {
            return JsonResult.error("获取 info_hash 失败", e.getMessage());
        }
    }

    @GetMapping("/getSeeders")
    public JsonResult getSeeders(@RequestParam("torrentId") Integer torrentId) {
        try {
            // 使用 torrentId 直接查询种子信息
            Torrent torrent = torrentService.getById(torrentId);

            if (torrent != null) {
                return JsonResult.success(torrent.getSeeders());
            } else {
                return JsonResult.error("种子不存在");
            }
        } catch (Exception e) {
            return JsonResult.error("获取做种人数失败", e.getMessage());
        }
    }





}




